package com.tps.cloud.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.annotations.VisibleForTesting;
import com.tps.cloud.exception.BusinessException;
import com.tps.cloud.system.dto.SystemDictDto;
import com.tps.cloud.system.entity.SystemDict;
import com.tps.cloud.system.entity.SystemDictItem;
import com.tps.cloud.system.mapper.SystemDictItemMapper;
import com.tps.cloud.system.mapper.SystemDictMapper;
import com.tps.cloud.system.param.SystemDictParam;
import com.tps.cloud.system.service.SystemDictService;
import com.tps.cloud.system.vo.SystemDictVo;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典类型表(SystemDict)表服务实现类
 *
 */
@Service
@AllArgsConstructor
public class SystemDictServiceImpl extends ServiceImpl<SystemDictMapper, SystemDict> implements SystemDictService {

    private final MessageSourceAccessor messages;

    private final SystemDictItemMapper itemMapper;

    @Override
    public Long createDictType(SystemDictDto systemDictDto) {
        //验证字典类型唯一性
        validateDictTypeUnique(systemDictDto);
        SystemDict systemDict = new SystemDict();
        BeanUtils.copyProperties(systemDictDto, systemDict);
        this.save(systemDict);
        return systemDict.getId();
    }

    @Override
    public void updateDictType(SystemDictDto systemDictDto) {
        //验证id是否存在
        validateDictTypeExists(systemDictDto.getId());
        //验证字典类型唯一性
        validateDictTypeUnique(systemDictDto);
        SystemDict systemDict = new SystemDict();
        BeanUtil.copyProperties(systemDictDto, systemDict);
        this.updateById(systemDict);
    }

    @Override
    public void deleteDictTypeByIds(List<Long> ids) {
        if(CollUtil.isEmpty(ids)){
            return;
        }
        //批量删除字典类型
        baseMapper.deleteByIds(ids);
        //批量删除字典值
        itemMapper.delete(Wrappers.<SystemDictItem>lambdaQuery().in(SystemDictItem::getDictId, ids));
    }

    @Override
    public SystemDictVo getDictType(Long id) {
        SystemDict systemDict=baseMapper.selectById(id);
        return BeanUtil.toBean(systemDict, SystemDictVo.class);
    }

    @Override
    public IPage selectDictTypePage(Page page, SystemDictParam systemDictParam) {
        return page(page,
                Wrappers.<SystemDict>lambdaQuery()
                        .like(StrUtil.isNotBlank(systemDictParam.getType()), SystemDict::getType, systemDictParam.getType())
                        .like(StrUtil.isNotBlank(systemDictParam.getChValue()), SystemDict::getChValue, systemDictParam.getChValue())
                        .like(StrUtil.isNotBlank(systemDictParam.getEnValue()), SystemDict::getChValue, systemDictParam.getEnValue()));
    }

    /**
     * 验证类型唯一性
     * @param id
     */
    @VisibleForTesting
    void validateDictTypeExists(Long id) {
        if (id == null) {
            throw new BusinessException(messages.getMessage("System.Id.IsNull"));
        }
        SystemDict systemDict = baseMapper.selectById(id);
        if (systemDict == null) {
            throw new BusinessException(messages.getMessage("SystemDictDto.Id.NotExist"));
        }
    }

    /**
     * 验证类型唯一性
     * @param systemDictDto
     */
    @VisibleForTesting
    void validateDictTypeUnique(SystemDictDto systemDictDto) {
        SystemDict systemDict = baseMapper.selectOne(SystemDict::getType, systemDictDto.getType());
        if (systemDict == null
                || ObjUtil.equal(systemDict.getId(), systemDictDto.getId())) {
            return;
        }
        throw new BusinessException(messages.getMessage("SystemDictDto.Type.Exist"));
    }
}
